package com.dj.controller;

import ca.uhn.fhir.rest.annotation.*;
import ca.uhn.fhir.rest.api.MethodOutcome;
import ca.uhn.fhir.rest.param.StringParam;
import ca.uhn.fhir.rest.server.exceptions.ResourceVersionConflictException;
import com.dj.service.ProcedureRequestService;
import com.dj.util.CrudOperationUtil;
import org.hl7.fhir.dstu3.model.IdType;
import org.hl7.fhir.dstu3.model.Meta;
import org.hl7.fhir.dstu3.model.ProcedureRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

/**
 * @author cyf
 * @description 患者
 * @create 2018-06-27 10:54
 **/

@Controller
public class ProcedureRequestController {

    private static final Logger logger = LoggerFactory.getLogger(ProcedureRequestController.class);

   @Autowired
   private ProcedureRequestService procedureRequestService;

    /**
     * 创建
     * @param procedureRequest
     * @return
     */
    @Create
    @Transactional
    public MethodOutcome create(@ResourceParam ProcedureRequest procedureRequest) {
        long startTime = System.currentTimeMillis();
        logger.info("procedureRequest create start!!!");

        Boolean flag = false;
        String patientId = null;
        try {
            String[] subject = procedureRequest.getSubject().getReference().split("Patient/");
            String[] context = procedureRequest.getContext().getReference().split("Encounter/");
            patientId = subject[subject.length - 1];
            String encounterId = context[context.length - 1];
            flag = procedureRequestService.isExist(patientId,encounterId);
        } catch (Exception e) {
            logger.error("Exception, Query the associated ProcedureRequest ID error,", e);
        }
        if (flag) { //执行 create
            logger.info("relation id is exist, the id is {}",patientId);
            IdType idType = procedureRequestService.saveProcedureRequest(procedureRequest);
            return  CrudOperationUtil.getMethodOutcome(idType, startTime);
        } else { // 关联患者不存在.
            logger.info("relation id is not exist, the id is {}",patientId);
            return CrudOperationUtil.getEmptyMethodOutcome(1);//0 - patient ;1 - encounter
        }
    }

    /**
     * 更新
     * @param theId
     * @param procedureRequest
     * @return
     */
    @Update
    @Transactional
    public MethodOutcome update(@IdParam IdType theId, @ResourceParam ProcedureRequest procedureRequest) {
        long startTime = System.currentTimeMillis();
        logger.info("ProcedureRequest update start!!!");

        String id = theId.getIdPart();
        String versionId = theId.getVersionIdPart(); // this will contain the ETag
        //String currentVersion = "1"; // populate this with the current version

        IdType idType = procedureRequestService.updateProcedureRequest(id, procedureRequest);
        String updateVersion = String.valueOf(Long.valueOf(idType.getVersionIdPart()) - 1L);
        if (versionId != null && !versionId.equals("")) {
            if (id.equals(idType.getIdPart()) && versionId.equals(updateVersion)) {
                return CrudOperationUtil.getMethodOutcome(idType, startTime);
            } else {
                throw new ResourceVersionConflictException("Expected version " + versionId);
            }
        } else {
            return CrudOperationUtil.getMethodOutcome(idType, startTime);
        }
    }

    /**
     * 查询id 历史
     * @param idType
     * @return
     */
    @Read(version = true)
    public ProcedureRequest getByIdOrVersion(@IdParam IdType idType) {
        logger.info("ProcedureRequest readOrVread  start!!!, param is {}", idType);
        ProcedureRequest procedureRequest = new ProcedureRequest();

        String id = idType.getIdPart();

        Meta meta = new Meta();
        String version = null;
        if (idType.hasVersionIdPart()) {
            //历史记录
            logger.info("query history!");
            version = idType.getVersionIdPart();
            Date date = procedureRequestService.getHistoryLastUpdatTime(id, version);
            if (date != null) {
                meta.setLastUpdated(date);
                procedureRequest = procedureRequestService.getByIdAndVersion(id, version);
            } else {
                logger.info("Error, This historical version does not exist, the version is {}",version);
            }
        } else {
            logger.info("query the current record!");
            //当前记录
            meta.setLastUpdated(procedureRequestService.getLastUpdatTime(id));
            procedureRequest = procedureRequestService.getById(id);
        }
        if (!procedureRequest.isEmpty()) {
            procedureRequest.setMeta(meta);
        } else {
            String vS = version == null ? "" : "/_history/" + version;
            procedureRequest = CrudOperationUtil.getQueryEmpty(procedureRequest,"ProcedureRequest/"+id + vS);
        }
        return procedureRequest;
    }

    /**
     * 查询所有历史记录
     * @param theId
     * @return
     */
    @History(type = ProcedureRequest.class)
    public List<ProcedureRequest> getProcedureRequestHistory(@IdParam IdType theId) {
        logger.info("ProcedureRequest getAllProcedureRequestHistory start!!!, theId={}", theId);
        String id = theId.getIdPart();
        return procedureRequestService.getAllProcedureRequestById(id);
    }


    /*检查项目*/
    /*<code>
        <coding>
            <system value="http://loinc.org"/>
            <code value="80859-2"/>
            <display value="心脏彩色多普勒超声"/>
        </coding>
    </code>*/
    /**
     * 检查项目  code 编码
     * @param code
     * @return
     */
    //@Search()
    //public List<ProcedureRequest> searchByCode(@RequiredParam(name = "code") StringParam code) {
    //    logger.info("ProcedureRequest searchByCode start!!!, code={}", code);
    //    return procedureRequestService.getByCode(code);
    //}

    /**
     * 检查项目  code 项目名称
     * @param code
     * @return
     */
    @Search()
    public List<ProcedureRequest> searchByCodeText(@RequiredParam(name = "code:text") StringParam code) {
        logger.info("ProcedureRequest searchByCode start!!!, code={}", code);
        return procedureRequestService.getByCode(code);
    }



    /**
     * 删除
     * @param theId
     * @return
     */
    @Delete(type = ProcedureRequest.class)
    @Transactional
    public MethodOutcome delete(@IdParam IdType theId) {
        long startTime = System.currentTimeMillis();
        logger.info("ProcedureRequest delete start!!!, theId={}", theId);
        return CrudOperationUtil.delete(theId, procedureRequestService::deleteProcedureRequest, startTime);

    }



}
